package com.bjpowernode.util;

import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.bjpowernode.entity.TUser;

import java.util.HashMap;
import java.util.Map;

public class JavaJwtUtil {
    //自定义密钥
    public static final String secret = "0S/12dSd0=;2Sfdjkgh30PYs";

    public static void main(String[] args) {
        TUser user = new TUser();
        user.setId(123);
        user.setLoginAct("cat");
        String userJson = JSONUtil.toJsonStr(user);
        String token = createToken(userJson);
        System.out.println(token);
        System.out.println(verifyToken(token));
        parseToken(token);
    }

    //生成jwt
    public static String createToken(String userJson){
        //组装头数据
        Map<String,Object> header = new HashMap<>();
        header.put("alg","HS256");  //指定令牌生成的算法
        header.put("typ","JWT");    //指定令牌的类型
        return JWT.create()
                //头信息
                .withHeader(header)
                //自定义数据，也就是jwt中间的负载部分的数据，大多数情况下就是用户数据
                .withClaim("user",userJson)
                //负载可以负载多个数据
                .withClaim("phone","12315613123")
                //签名算法以及密钥
                .sign(Algorithm.HMAC256(secret));
    }

    //验证jwt有没有被篡改过
    public static Boolean verifyToken(String token){
        try{
            //使用密钥创建一个jwt的验证对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
            //验证jwt,如果验证没有抛出异常，则验证通过。否则验证不通过
            jwtVerifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    //解析jwt令牌
    public static String parseToken(String token){
        try{
            //使用密钥创建一个解析对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
            //验证jwt,得到一个解码后的jwt对象
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            //通过解码后的jwt对象获取负载的数据
            Claim user = decodedJWT.getClaim("user");
            Claim phone = decodedJWT.getClaim("phone");
            System.out.println(user.asString());
            System.out.println(phone.asString());
            return user.asString();
        }catch (TokenExpiredException e){
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
}
